//
//  SinusoidGenerator.m
//  CocoaSynth
//
//  Created by Pierre DUCHENE on 09/02/10.
//  Copyright 2010 Pierre DUCHENE. All rights reserved.
//

#import "SinusoidGenerator.h"
#import "SampleProtocol.h"
#import "Sample.h"
#import "System.h"
#import "AudioWrapper.h"
#import "SignalVisualizer.h"

@implementation SinusoidGenerator

#pragma mark -
#pragma mark Accessors

@synthesize module;

#pragma mark -
#pragma mark Memory Management

- (id)init
{
	if (self = [super init]) {
		module = nil;
	}
	return self;
}

- (void)dealloc
{
	[module release];
	module = nil;
	
	[super dealloc];
}

#pragma mark -
#pragma mark ComputingStrategyProtocol

- (id<SampleProtocol>)execute
{
	id<SampleProtocol> result = [[Sample alloc] init];
	
	// Get system infos
	System* system = [System sharedSystem];
	double time = [system time];
	NSUInteger sampleSize = [system sampleSize];
	double samplePosition = [system samplePosition];
	double sampleRate = [system sampleRate];
	double delta_t = 1.f/sampleRate;
	
	// Get module infos
	float f_0 = [module baseFrequency];
	float k = [module exponentialFrequency];
	NSArray* fm = [[module inputSample] voltages];
	if ((fm == nil) || [[fm objectAtIndex:1] floatValue] != 0) {
		NSMutableArray* tempResult = [[NSMutableArray alloc] init];
		float Vfm;
		float f;
		float two_pi = 2 * M_PI;
		for (int i = 0; i < sampleSize; i++) {
			// Compute outputfrequency
			Vfm = [[fm objectAtIndex:i] floatValue];
			f = f_0 * pow(2, (k + Vfm)); // f = f0 * 2^(k+Vfm)
			// Generate a simple sinusoid
			float newValue = sin( two_pi * f * time) * kDefaultAmplitude;
			[tempResult insertObject:[NSNumber numberWithFloat:newValue] atIndex:i];
			
			time += delta_t;
		}
		[result setVoltages:[NSArray arrayWithArray:tempResult]];
		[tempResult release];
	}
	else {
		[result setVoltages:fm];
	}

	[system setSamplePosition:samplePosition];
	
	return [result autorelease];
}


@end
